; Myrmidon 
; TAB=4
CYLS	EQU		10				; 常数声明，用来指代读取的柱面数

		ORG		0x7c00			; 指出程序的装载地址，根据规定0x00007c00-0x00007dff是启动区内容的装载地址

; 以下是标准FAT12格式软盘用的代码

		JMP		entry			; 跳转执行位于0x7c50的entry程序
		DB		0x90
		DB		"MYRMIipl"		; 启动区的名字可以是自定义的字符串（8字节）
		DW		512				; 每个扇区sector的大小（必须是512字节）
		DB		1				; 簇cluster的大小（必须是1个扇区）
		DW		1				; FAT的初始位置（通常从第一个扇区开始）
		DB		2				; FAT的个数（必须是2）
		DW		224				; 根目录的大小（一般设成224）
		DW		2880			; 该磁盘的大小（必须是2880扇区）
		DB		0xf0			; 磁盘的种类（必须是0xf0）
		DW		9				; FAT的长度（必须是9扇区）
		DW		18				; 一个磁道track有18个扇区（必须是18个）
		DW		2				; 磁头数（必须是两个）
		DD		0				; 不使用分区（必须为0）
		DD		2880			; 重写一次磁盘大小
		DB		0,0,0x29		; 默认
		DD		0xffffffff		; 卷标号码
		DB		"MYRMIDON-OS"	; 磁盘的名称(11字节)
		DB		"FAT12   "		; 磁盘格式名称
		RESB	18				; 空出18字节

; 程序核心

entry:							; 地址为0x7c50
		MOV		AX,0			; 寄存器初始化
		MOV		SS,AX			; 赋值给栈段寄存器
		MOV		SP,0x7c00		; 栈指针寄存器赋值
		MOV		DS,AX			; 数据段寄存器

; 读取磁盘,将内容读取到内存中

		MOV		AX,0X0820		; 因启动区占据了从0x7c00到0x7dff的地址，并且0x8000到0x81ff是留给启动区的2x16x16=512字节内存
		MOV 	ES,AX			; 将地址赋给段寄存器
		MOV		CH,0			; 柱面0
		MOV		DH,0			; 磁盘
		MOV		CL,2			; 扇区2，启动区在1扇区，所以从2扇区开始读盘

readloop:		
		MOV		SI,0			; SI是源地址寄存器，此处用于记录失败次数，此处是初始化，说明跳转到此处之前未出现错误

;多次尝试

retry:  
		MOV		AH,0x02			; 读入磁盘
		MOV		AL,1			; 一次读1个扇区
		MOV		BX,0			; 缓冲地址，校验与寻道时不使用
		MOV		DL,0x00			; A驱动器
		INT		0x13			; 引发中断，调用BIOS,磁盘读写，扇区校验verify和寻道seek
		JNC		next		    ; 没出错就跳转到fin，标志位为0就跳转
;JNC：jump if not carry
		ADD		SI,1			; 给SI加1
		CMP		SI,5			; 看尝试次数是否>=5
		JAE		error			; 如果>=5就跳转到error
;JAE：jump if above or equal
		MOV		AH,0x00			; 系统复位
		MOV		DL,0x00			; A驱动器
		INT		0x13			; 重置驱动器
		JMP		retry			; 反复尝试
		
next：
		MOV		AX,ES			;
		ADD		AX,0x0020		;
		MOV		ES,AX			; 将ES的地址后移0x0020，相当于读下一个扇区
		ADD		CL,1			; 往CL里加1（扇区号加1）
		CMP		CL,18			; 看是否到达18个扇区
		JBE		readloop		; 如果小于等于18，那么跳转到readloop
;JBE= jump if below or equal
		MOV		CL,1			; 将计数寄存器重新置1
		ADD		DH,1			; 
		CMP		DH,2			; 将DH与2比较,要求读两个柱面（每个柱面18个扇区）
		JB		readloop		;
;JBE= jump if below				
		MOV		DH,0			;
		ADD		CH,1		    ; 利用计数寄存器的高八位看是否读完要求的柱面数
		CMP		CH,CYLS
		JB		readloop		;

; 休眠

fin:
		HLT						; 让CPU停止，等待命令
		JMP		fin 			; 无限循环


error:
		MOV		SI,msg			; 将展示信息地址赋给源变址寄存器
		
putloop:
		MOV     AL,[SI]			; 将SI地址指向的内容赋给累加寄存器（8字节）
		ADD		SI,1			; SI加1，地址指向下一存储单元
		CMP		AL,0			; 将AL内容和0比较	
		JE		fin				; 如果上一步相等就跳转到fin
;JE：jump if equal
		MOV		AH,0x0e			; 显示一个文字
		MOV		BX,15			; 设定字体颜色
		INT		0x10			; 调用显卡BIOS
		JMP		putloop			; 循环调用

; 显示内容
		
msg:
		DB		0x0a, 0x0a		; 换行两次
		DB		"load error"	; 打印输出字符
		DB		0x0a			; 换行
		DB		0

		RESB	0x7dfe-$		; 填写0x00直到0x7dfe

		DB		0x55, 0xaa		; 扇区最后两个字节，指示启动区
